<template>
  <view class="image-selector">
    <!-- Konva画布容器 -->
    <view
      :id="containerId"
      class="canvas-container"
      :style="{ width: width + 'px', height: height + 'px' }"
    >
    </view>

    <!-- 新增框选框按钮 -->
    <view class="add-box-btn" @tap="addNewSelectionBox" v-if="!isRotated">
      <text class="add-icon">+</text>
    </view>
  </view>
</template>

<script>
import Konva from "konva";
import {
  loadImage,
  calculateImageBounds,
  getImageInfo,
} from "@/utils/image-utils.js";
import {
  relativeToAbsolute,
  generateId,
  validateCoordinates,
} from "@/utils/coordinate-utils.js";
import {
  createStage,
  createImageLayer,
  createSelectionLayer,
  createKonvaImage,
  createSelectionBox,
  addSelectionBoxEvents,
  getSelectionCoordinates,
  clearLayer,
  destroyStage,
  toggleResizeHandles,
} from "@/utils/konva-utils.js";

export default {
  name: "ImageSelector",
  props: {
    // 图片URL
    imageUrl: {
      type: String,
      required: true,
    },
    // 初始坐标数组
    coordinates: {
      type: Array,
      default: () => [],
    },
    // 画布宽度
    width: {
      type: Number,
      default: 375,
    },
    // 画布高度
    height: {
      type: Number,
      default: 600,
    },
    // 旋转角度
    rotation: {
      type: Number,
      default: 0,
    },
    // 是否允许新增框选框
    allowAddBox: {
      type: Boolean,
      default: true,
    },
  },

  data() {
    return {
      // Konva相关
      stage: null,
      imageLayer: null,
      selectionLayer: null,
      konvaImage: null,

      // 图片信息
      imageInfo: null,
      imageBounds: null,

      // 内部状态
      currentCoordinates: [],
      isDragging: false,

      // 容器ID
      containerId: "konva-" + Date.now(),
    };
  },

  computed: {
    isRotated() {
      return this.rotation !== 0;
    },
  },

  watch: {
    coordinates: {
      handler(newVal) {
        if (newVal && newVal !== this.currentCoordinates) {
          this.currentCoordinates = JSON.parse(JSON.stringify(newVal));
          this.drawSelectionBoxes();
        }
      },
      deep: true,
      immediate: true,
    },

    rotation() {
      this.updateImageRotation();
      this.drawSelectionBoxes();
    },

    imageUrl() {
      this.loadAndDisplayImage();
    },
  },

  mounted() {
    this.$nextTick(() => {
      this.initializeCanvas();
    });
  },

  beforeUnmount() {
    this.cleanup();
  },

  methods: {
    // 初始化画布
    async initializeCanvas() {
      try {
        // 创建Konva舞台
        this.stage = createStage(this.containerId, this.width, this.height);
        this.imageLayer = createImageLayer();
        this.selectionLayer = createSelectionLayer();

        this.stage.add(this.imageLayer);
        this.stage.add(this.selectionLayer);

        // 添加舞台点击事件，点击空白区域时保持控制点显示
        this.stage.on("click tap", (e) => {
          // 如果点击的是空白区域
          if (e.target === this.stage) {
            const allBoxes = this.selectionLayer.find(".selection-box");
            allBoxes.forEach((box) => {
              // 控制点始终显示，不隐藏
              toggleResizeHandles(box, true);
            });
          }
        });

        // 加载图片
        await this.loadAndDisplayImage();

        // 绘制初始框选框
        this.drawSelectionBoxes();

        // 触发初始化完成事件
        this.$emit("ready");
      } catch (error) {
        console.error("初始化画布失败:", error);
        this.$emit("error", error);
      }
    },

    // 加载并显示图片
    async loadAndDisplayImage() {
      if (!this.imageUrl) return;

      try {
        // 获取图片信息
        this.imageInfo = await getImageInfo(this.imageUrl);

        // 加载图片元素
        const imageElement = await loadImage(this.imageUrl);

        // 计算图片在画布中的显示边界
        this.imageBounds = calculateImageBounds(
          this.imageInfo.width,
          this.imageInfo.height,
          this.width,
          this.height
        );

        // 清空图片图层
        clearLayer(this.imageLayer);

        // 创建Konva图片对象
        this.konvaImage = createKonvaImage(
          imageElement,
          this.imageBounds,
          this.rotation
        );

        // 添加到图层
        this.imageLayer.add(this.konvaImage);
        this.imageLayer.batchDraw();
      } catch (error) {
        console.error("加载图片失败:", error);
        this.$emit("error", error);
      }
    },

    // 更新图片旋转
    updateImageRotation() {
      if (!this.konvaImage) return;

      this.konvaImage.rotation(this.rotation);

      // 调整旋转中心点
      if (this.rotation !== 0) {
        this.konvaImage.offsetX(this.imageBounds.width / 2);
        this.konvaImage.offsetY(this.imageBounds.height / 2);
        this.konvaImage.x(this.imageBounds.x + this.imageBounds.width / 2);
        this.konvaImage.y(this.imageBounds.y + this.imageBounds.height / 2);
      } else {
        this.konvaImage.offsetX(0);
        this.konvaImage.offsetY(0);
        this.konvaImage.x(this.imageBounds.x);
        this.konvaImage.y(this.imageBounds.y);
      }

      this.imageLayer.batchDraw();
    },

    // 绘制框选框
    drawSelectionBoxes() {
      if (!this.imageBounds || this.isRotated) {
        // 旋转状态下不显示框选框
        clearLayer(this.selectionLayer);
        return;
      }

      // 清空现有框选框
      clearLayer(this.selectionLayer);

      // 验证坐标数据 (传入true表示使用相对坐标0-1范围验证)
      if (!validateCoordinates(this.currentCoordinates, true)) {
        console.warn("坐标数据格式不正确");
        return;
      }

      // 绘制每个框选框
      this.currentCoordinates.forEach((coord) => {
        const absoluteCoord = relativeToAbsolute(
          coord,
          this.imageBounds.width,
          this.imageBounds.height
        );

        // 调整坐标到图片位置
        absoluteCoord.x += this.imageBounds.x;
        absoluteCoord.y += this.imageBounds.y;

        // 创建框选框
        const selectionBox = createSelectionBox(absoluteCoord, coord.id);
        selectionBox.name("selection-box");

        // 添加事件监听
        addSelectionBoxEvents(
          selectionBox,
          this.imageBounds,
          this.onDragStart,
          this.onDragEnd,
          this.onResize
        );

        // 添加删除事件
        this.addDeleteEvent(selectionBox);

        // 添加到图层
        this.selectionLayer.add(selectionBox);
      });

      this.selectionLayer.batchDraw();
    },

    // 添加删除事件
    addDeleteEvent(selectionBox) {
      const deleteHandler = (e) => {
        e.cancelBubble = true;

        const boxId = selectionBox.id();

        // 从坐标数组中移除
        this.currentCoordinates = this.currentCoordinates.filter(
          (coord) => coord.id !== boxId
        );

        // 销毁框选框
        selectionBox.destroy();

        // 安全地重绘图层
        if (this.selectionLayer) {
          this.selectionLayer.batchDraw();
        }

        // 触发删除事件
        this.$emit("delete", boxId);

        // 触发坐标更新事件
        this.emitCoordinatesChange();
      };

      selectionBox.deleteButton.on("click tap", deleteHandler);
      selectionBox.deleteIcon.on("click tap", deleteHandler);
    },

    // 拖拽开始
    onDragStart(selectionBox) {
      this.isDragging = true;
      this.$emit("dragStart", selectionBox.id());
    },

    // 拖拽结束
    onDragEnd(selectionBox) {
      this.isDragging = false;
      this.$emit("dragEnd", selectionBox.id());

      // 更新坐标数据
      this.updateCoordinatesFromBoxes();
    },

    // 调整大小
    onResize(selectionBox) {
      this.$emit("resize", selectionBox.id());

      // 更新坐标数据
      this.updateCoordinatesFromBoxes();
    },

    // 从框选框更新坐标数据
    updateCoordinatesFromBoxes() {
      if (!this.imageBounds) return;

      const currentCoords = getSelectionCoordinates(
        this.selectionLayer,
        this.imageBounds
      );

      // 更新坐标数组，保持原有顺序
      this.currentCoordinates = this.currentCoordinates.map((coord) => {
        const updated = currentCoords.find((c) => c.id === coord.id);
        return updated || coord;
      });

      // 触发坐标更新事件
      this.emitCoordinatesChange();
    },

    // 触发坐标变更事件
    emitCoordinatesChange() {
      this.$emit("coordinatesChange", this.currentCoordinates);
    },

    // 新增框选框
    addNewSelectionBox() {
      if (this.isRotated || !this.imageBounds) return;

      // 创建新的框选框坐标（在图片中央）
      const newCoord = {
        id: generateId(),
        x: 0.3,
        y: 0.3,
        width: 0.4,
        height: 0.3,
      };

      // 添加到坐标数组
      this.currentCoordinates.push(newCoord);

      // 重新绘制
      this.drawSelectionBoxes();

      // 触发新增事件
      this.$emit("add", newCoord);

      // 触发坐标更新事件
      this.emitCoordinatesChange();
    },

    // 获取当前坐标
    getCurrentCoordinates() {
      return JSON.parse(JSON.stringify(this.currentCoordinates));
    },

    // 设置坐标
    setCoordinates(coordinates) {
      if (validateCoordinates(coordinates, true)) {
        this.currentCoordinates = JSON.parse(JSON.stringify(coordinates));
        this.drawSelectionBoxes();
        this.emitCoordinatesChange();
      }
    },

    // 清空所有框选框
    clearAllBoxes() {
      this.currentCoordinates = [];
      clearLayer(this.selectionLayer);
      this.emitCoordinatesChange();
    },

    // 清理资源
    cleanup() {
      if (this.stage) {
        destroyStage(this.stage);
        this.stage = null;
        this.imageLayer = null;
        this.selectionLayer = null;
        this.konvaImage = null;
      }
    },
  },
};
</script>

<style scoped>
.image-selector {
  position: relative;
  width: 100%;
  height: 100%;
}

.canvas-container {
  width: 100%;
  height: 100%;
}

.add-box-btn {
  position: absolute;
  top: 20px;
  right: 20px;
  width: 48px;
  height: 48px;
  background: #007aff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(0, 122, 255, 0.3);
  z-index: 10;
}

.add-box-btn:active {
  transform: scale(0.95);
  background: #0056b3;
}

.add-icon {
  color: white;
  font-size: 24px;
  font-weight: bold;
  line-height: 1;
}
</style>
